package middleware

import (
	"bufio"
	"github.com/Sir-yuChen/funAnalyse/global"
	"github.com/Sir-yuChen/funAnalyse/model"
	"github.com/Sir-yuChen/funAnalyse/utils"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"os"
	"strings"
	"time"
)

// InitTplDBMiddleware 项目启动时 将模板源文件 扫描DB
func InitTplDBMiddleware() gin.HandlerFunc {
	absPath := utils.GetAbsPath()
	//1. 扫描系统中的所有模板文件
	filePaths, err := utils.GetAllTplFile(absPath+global.GVA_CONFIG.Tpl.TplBasicPath, nil)
	if err != nil {
		global.GVA_LOG.Error("模板文件初始化异常 >>>> 获取所以源模板文件异常", zap.Error(err))
		os.Exit(-1)
	}
	if len(filePaths) == 0 {
		global.GVA_LOG.Info("模板文件初始化 >>>> 无源模板文件")
		return func(c *gin.Context) {
			c.Next()
		}
	}
	//2. 解析模板源信息 类型0
	for _, p := range filePaths {
		stockCodeTpl := handlerTplFile(p)
		if stockCodeTpl == nil {
			continue
		}
		var st model.StockCodeTpl
		//校验数据库中是否已经存在当前模板信息
		err := global.GVA_DB.Model(&model.StockCodeTpl{}).Where("tpl_name = ?", stockCodeTpl.TplName).First(&st).Error
		if err != nil && err.Error() != "record not found" {
			global.GVA_LOG.Error("模板文件初始化异常 >>>> 校验文件模板名是否已存在异常", zap.Any("stockCodeTpl", stockCodeTpl), zap.Error(err))
			os.Exit(-1)
		}
		if st != (model.StockCodeTpl{}) {
			if st.TplPath != stockCodeTpl.TplPath {
				stockCodeTpl.Id = st.Id
				//模板路径不同更新路径
				err := global.GVA_DB.Model(&model.StockCodeTpl{}).Where("id=?", st.Id).Updates(stockCodeTpl).Error
				if err != nil {
					global.GVA_LOG.Error("模板文件初始化异常 >>>> 更新模板路径异常", zap.Any("stockCodeTpl", stockCodeTpl), zap.Error(err))
					os.Exit(-1)
				}
			} else {
				global.GVA_LOG.Warn("模板文件初始化 >>>> 文件模板名已存在,当前模板无法录入数据库", zap.Any("stockCodeTpl", stockCodeTpl), zap.Error(err))
			}
			continue
		}
		err = global.GVA_DB.Model(&model.StockCodeTpl{}).Create(stockCodeTpl).Error
		if err != nil {
			global.GVA_LOG.Error("模板文件初始化异常 >>>> 源模板文件Insert异常", zap.Any("stockCodeTpl", stockCodeTpl), zap.Error(err))
			os.Exit(-1)
		}
	}
	global.GVA_LOG.Info("模板文件初始化 >>>> 初始化完成")
	return func(c *gin.Context) {
		// 处理请求
		c.Next()
	}
}

func handlerTplFile(path string) *model.StockCodeTpl {
	//1.校验文件是否存在
	exist, err := utils.FileExist(path)
	if err != nil {
		global.GVA_LOG.Error("模板文件初始化异常 >>>> 校验源模板文件是否存在异常", zap.Any("path", path), zap.Error(err))
		return nil
	}
	if !exist {
		global.GVA_LOG.Error("模板文件初始化异常 >>>> 校验源模板文件不存在", zap.Any("path", path), zap.Error(err))
		return nil
	}
	//2.解析文件 获取文件名
	file, err := os.Open(path)
	defer file.Close()
	if err != nil {
		global.GVA_LOG.Error("模板文件初始化异常 >>>> 读取源模板文件异常", zap.Any("path", path), zap.Error(err))
		return nil
	}
	reader := bufio.NewReader(file)
	strBytes, _, err := reader.ReadLine()
	if err != nil {
		global.GVA_LOG.Error("模板文件初始化异常 >>>> 读取源模板文件获取模板名异常", zap.Any("path", path), zap.Error(err))
		return nil
	}
	//{{/* 控制层总路由 */}} 正侧提取
	//compile := regexp.MustCompile(`{{/*(.*?)*/}}`)
	//submatch := compile.FindStringSubmatch(string(strBytes))
	i := lastIndexStr(string(strBytes), "*")
	st := string(strBytes)[:i]
	in := lastIndexStr(st, "*")
	st = string(strBytes)[in+1 : i]
	index := lastIndexStr(path, "/")
	str := path[:index]
	indext := lastIndexStr(str, "/")
	tplPath := str[indext+1:]
	if st == "" {
		global.GVA_LOG.Error("模板文件初始化异常 >>>> 源模板文件 模板名未按规则写入", zap.Any("path", path), zap.Error(err))
		return nil
	}
	//组装参数
	now := model.LocalTime(time.Now())
	tpl := model.StockCodeTpl{
		TplName:     strings.TrimSpace(st),
		TplPath:     path,
		TplAutoPath: tplPath,
		TplAutoName: "",
		TplType:     0,
		Status:      "Y",
		TplUseCount: 0,
		CreateBy:    "InitSys",
		Remark:      "",
		CreateTime:  &now,
		LastUpdTime: &now,
	}
	return &tpl
}
func lastIndexStr(str string, c string) int {
	lastInd := strings.LastIndex(str, c)
	if lastInd == -1 && c == "/" {
		//说明字符串不存在
		lastInd = strings.LastIndex(str, "\\")
	}
	return lastInd
}
